
package pl.genapp.stocksense;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;

import pl.genapp.appsense.R;
import pl.genapp.stocksense.libraries.FacebookHelper;
import pl.genapp.stocksense.libraries.StockQuotesProvider;
import pl.genapp.stocksense.libraries.TwitterHelper;
import pl.genapp.stocksense.others.PostExecuteReaction;
import pl.genapp.stocksense.others.StockSenseState;
import pl.genapp.stocksense.others.TimeLineClickListener;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

public class StackSense extends FragmentActivity {
	
	public final static String SHARED_PREFERENCE_WATCHLIST = "watchlist";
	
	private static final int MIN_SPLASH_DISPLAY_TIME = 2000;
	private long timeSinceActivityStarted;
	
	private View watchlist_header_new;
	private View watchlist_header_confirm;
	private ListView entitiesList;
	private LinearLayout searchMenu;
	private EditText searchValue;
	private View[] timelineButtons;
	private LinearLayout splashScreen;
	
	private BaseAdapter normalAdapter;
	
	private List<TimeLineClickListener> timelineListeners = new ArrayList<TimeLineClickListener>();
	private SharedPreferences watchlistSP;
	
	private ListView.OnItemClickListener entitiesListClickListener;
	private View.OnClickListener watchlistNewListener;
	private View.OnClickListener watchlistConfirmListener;
	private View.OnClickListener timelineListener;
	
	private TwitterHelper twitterHelper;
	private FacebookHelper facebookHelper = new FacebookHelper(this);
	
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);
		
		modifyClickedWatchlist(timelineButtons[((StockSenseState) getApplication()).getSelectedMonths() / 3 - 1]);
		
	}
	
	protected void onNewIntent(Intent intent) {
		super.onNewIntent(intent);
		
		twitterHelper.twitterReceiveLoginData(intent);
		
	}
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		setContentView(R.layout.activity_stack_sense);
		
		LoginActivity.showLoginAsNeeded(this);
		
		preSetup();
		
		bindViews();
		
		createListeners();
		
		bindListeners();
		
		/**
		 * SplashScreen
		 */
		if (savedInstanceState == null) splashScreen.setVisibility(View.VISIBLE);
		
		/**
		 * Adapter
		 */
		normalAdapter = new EntitiesListAdapterNormal(watchlistSP);
		entitiesList.setAdapter(normalAdapter);
		
		/**
		 * MainScreenFragment
		 **/
		if (savedInstanceState == null) {
			MainScreenFragment mainFragment = new MainScreenFragment();
			FragmentManager fragmentManager = getSupportFragmentManager();
			FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
			fragmentTransaction.add(R.id.fragmentsSide, mainFragment);
			fragmentTransaction.commit();
		}
		
		/**
		 * Search
		 */
		searchValue = (EditText) findViewById(R.id.searchValue);
		searchValue.addTextChangedListener(searchTextWatcher);
		
		/**
		 * Helpers
		 */
		twitterHelper = new TwitterHelper(this);
	}
	
	void preSetup() {
		
		watchlistSP = getSharedPreferences(SHARED_PREFERENCE_WATCHLIST, 0);
		timeSinceActivityStarted = new Date().getTime();
		
	}
	
	void bindViews() {
		
		watchlist_header_new = findViewById(R.id.watchlist_new_entity);
		watchlist_header_confirm = findViewById(R.id.watchlist_header_confirm);
		entitiesList = (ListView) findViewById(R.id.entitiesList);
		searchMenu = (LinearLayout) findViewById(R.id.SearchMenuLinearView);
		timelineButtons = new View[] { findViewById(R.id.timeline_m_1), findViewById(R.id.timeline_m_3), findViewById(R.id.timeline_m_6), findViewById(R.id.timeline_m_9),
				findViewById(R.id.timeline_m_12) };
		splashScreen = (LinearLayout) findViewById(R.id.splashScreen);
		
	}
	
	void createListeners() {
		
		entitiesListClickListener = new ListView.OnItemClickListener() {
			
			public void onItemClick(AdapterView<?> arg0, View view, int position, long id) {
				
				Stack<String> stack = ((StockSenseState) getApplication()).getSelectedEntities();
				
				if (stack.isEmpty() || !((String) view.getTag()).equals(stack.peek())) {
					
					stack.push((String) view.getTag());
					
					// create fragment
					EntityScreenFragment entityFragment = EntityScreenFragment.newInstance((String) view.getTag());
					
					// fragment manager
					FragmentManager fragmentManager = getSupportFragmentManager();
					FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
					
					fragmentTransaction.replace(R.id.fragmentsSide, entityFragment);
					fragmentTransaction.addToBackStack((String) view.getTag());
					fragmentTransaction.commit();
					
					Log.d("stocksense", "Click on EntitiesList");
					
					normalAdapter.notifyDataSetChanged();
					
				}
				
			}
			
		};
		
		watchlistNewListener = new OnClickListener() {
			
			public void onClick(View v) {
				// setadapter
				entitiesList.setAdapter(new EntitiesListAdapterNew(watchlistSP));
				
				// menu
				searchMenu.setVisibility(View.VISIBLE);
				
				// buttony
				watchlist_header_confirm.setVisibility(View.VISIBLE);
				watchlist_header_new.setVisibility(View.INVISIBLE);
				
				entitiesList.setOnItemClickListener(null);
			}
		};
		
		watchlistConfirmListener = new OnClickListener() {
			
			public void onClick(View v) {
				// buttony
				watchlist_header_confirm.setVisibility(View.INVISIBLE);
				watchlist_header_new.setVisibility(View.VISIBLE);
				
				searchValue.setText("");
				
				// restore adapter
				normalAdapter = new EntitiesListAdapterNormal(watchlistSP);
				entitiesList.setAdapter(normalAdapter);
				
				// menu
				searchMenu.setVisibility(View.GONE);
				// update listview
				
				entitiesList.setOnItemClickListener(entitiesListClickListener);
				
			}
		};
		
		timelineListener = new OnClickListener() {
			
			public void onClick(View v) {
				
				((StockSenseState) getApplication()).setSelectedMonths(Integer.parseInt((String) v.getTag()));
				
				modifyClickedWatchlist(v);
				
				// Powiadamiamy
				for (TimeLineClickListener listener : timelineListeners) {
					listener.click(((StockSenseState) getApplication()).getSelectedMonths());
				}
				
			}
		};
	}
	
	void modifyClickedWatchlist(View v) {
		
		for (View view : timelineButtons)
			view.setBackgroundDrawable(null);
		
		v.setBackgroundDrawable(getResources().getDrawable(R.drawable.timeline_item_bg));
		
	}
	
	void bindListeners() {
		
		watchlist_header_new.setOnClickListener(watchlistNewListener);
		watchlist_header_confirm.setOnClickListener(watchlistConfirmListener);
		entitiesList.setOnItemClickListener(entitiesListClickListener);
		
		for (View v : timelineButtons)
			v.setOnClickListener(timelineListener);
	}
	
	public void onBackPressed() {
		// super.onBackPressed();
		
		Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.fragmentsSide);
		
		if (currentFragment instanceof EntityScreenFragment || currentFragment instanceof MainScreenFragment) if (!((StockSenseState) getApplication()).getSelectedEntities().isEmpty())
			((StockSenseState) getApplication()).getSelectedEntities().pop();
		else
			this.finish();
		
		getSupportFragmentManager().popBackStackImmediate();
		
		normalAdapter.notifyDataSetChanged();
		
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.activity_stack_sense, menu);
		return true;
	}
	
	public boolean onMenuItemSelected(int featureId, MenuItem item) {
		
		switch (item.getItemId()) {
		
			case R.id.menu_settings:
				
				Intent intent = new Intent(this, SettingsActivity.class);
				startActivity(intent);
				
				break;
		
		}
		
		return super.onMenuItemSelected(featureId, item);
	}
	
	public List<TimeLineClickListener> getTimelineListeners() {
		return timelineListeners;
	}
	
	public TwitterHelper getTwitterHelper() {
		return twitterHelper;
	}
	
	public FacebookHelper getFacebookHelper() {
		return facebookHelper;
	}
	
	/**
	 * EntitiesListAdapterNormal
	 */
	class EntitiesListAdapterNormal extends BaseAdapter {
		
		String[] items;
		SharedPreferences watchlistSP;
		HashMap<String, HashMap<String, Object>> asyncTaskResult = null;
		
		EntitiesListAdapterNormal(SharedPreferences watchlistSP) {
			
			this.watchlistSP = watchlistSP;
			
			List<String> choosen = new ArrayList<String>();
			
			Map<String, ?> map = watchlistSP.getAll();
			Set<String> keys = map.keySet();
			
			for (String key : keys) {
				if (watchlistSP.getBoolean(key, false)) choosen.add(key);
			}
			
			items = choosen.toArray(new String[choosen.size()]);
			// items = getResources().getStringArray(R.array.entities_array);
			
			PostExecuteReaction<HashMap<String, HashMap<String, Object>>> reaction = new PostExecuteReaction<HashMap<String, HashMap<String, Object>>>() {
				
				public void onSuccess(Context context, HashMap<String, HashMap<String, Object>> object) {
					asyncTaskResult = object;
					notifyDataSetChanged();
					
					long timeDiff = timeSinceActivityStarted + MIN_SPLASH_DISPLAY_TIME - new Date().getTime();
					
					// czy trzeba schowac splash screen?
					if (timeDiff < 0) {
						splashScreen.setVisibility(View.GONE);
					} else {
						
						new Handler().postDelayed(new Runnable() {
							
							public void run() {
								splashScreen.setVisibility(View.GONE);
							}
						}, timeDiff);
						
					}
					
				}
				
			};
			
			StockQuotesProvider quotes = new StockQuotesProvider(getApplicationContext(), reaction);
			
			StringBuilder sb = new StringBuilder();
			
			if (items.length > 0) {
				sb.append(items[0]);
				for (int i = 0; i < items.length; i++) {
					sb.append("+" + items[i]);
				}
				
				quotes.execute(quotes.createLink(sb.toString(), new String[] { StockQuotesProvider.SpecialTags.SYMBOL, StockQuotesProvider.SpecialTags.LAST_TRADE,
						StockQuotesProvider.SpecialTags.PERCENT_CHANGE_52_WEEK_LOW }));
			}
			
		}
		
		public int getCount() {
			return items.length;
		}
		
		public Object getItem(int arg0) {
			return arg0;
		}
		
		public long getItemId(int arg0) {
			return arg0;
		}
		
		public View getView(int position, View view, ViewGroup parent) {
			
			TextView listEntityName;
			TextView listEntityPrice;
			ImageView listEntityIcon;
			
			if (view == null) {
				view = getLayoutInflater().inflate(R.layout.entities_list_item_normal, null);
			}
			
			Boolean selected = false;
			if (!((StockSenseState) getApplication()).getSelectedEntities().isEmpty()) {
				
				String top = ((StockSenseState) getApplication()).getSelectedEntities().peek();
				
				if (top != null && top.equals(items[position])) {
					selected = true;
					view.setBackgroundDrawable(getResources().getDrawable(R.drawable.entities_list_bg_selected));
					
				}
				
			}
			
			if (!selected) view.setBackgroundDrawable(getResources().getDrawable(R.drawable.entities_list_bg));
			
			view.setTag(items[position]);
			
			// name
			listEntityName = (TextView) view.findViewById(R.id.listEntityName);
			listEntityName.setText(items[position]);
			
			// price
			listEntityPrice = (TextView) view.findViewById(R.id.listEntityPrice);
			listEntityPrice.setText("---");
			if (asyncTaskResult != null) {
				listEntityPrice.setText(asyncTaskResult.get(items[position]).get(StockQuotesProvider.SpecialTags.LAST_TRADE).toString());
			}
			
			// icon
			listEntityIcon = (ImageView) view.findViewById(R.id.listEntityIcon);
			listEntityIcon.setImageResource(R.drawable.loading);
			if (asyncTaskResult != null) {
				if (((Double) asyncTaskResult.get(items[position]).get(StockQuotesProvider.SpecialTags.PERCENT_CHANGE_52_WEEK_LOW)) > 0) {
					listEntityIcon.setImageResource(R.drawable.arrow_up);
				} else {
					listEntityIcon.setImageResource(R.drawable.arrow_down);
				}
			}
			
			return view;
			
		}
		
	}
	
	/**
	 * EntitiesListAdapterNew
	 */
	
	class EntitiesListAdapterNew extends BaseAdapter implements Filterable {
		
		String[] items;
		OnClickListener onAddClickListener;
		SharedPreferences watchlistSP;
		List<String> itemsFiltered;
		
		public EntitiesListAdapterNew(final SharedPreferences watchlistSP) {
			
			this.watchlistSP = watchlistSP;
			
			items = getResources().getStringArray(R.array.entities_array);
			itemsFiltered = new ArrayList();
			
			for (String s : items) {
				itemsFiltered.add(s);
			}
			
			onAddClickListener = new OnClickListener() {
				public void onClick(View v) {
					// get entity id
					int position = (Integer) v.getTag();
					
					// save to sp
					SharedPreferences.Editor editor = watchlistSP.edit();
					if (!watchlistSP.getBoolean(itemsFiltered.get(position), false))
						editor.putBoolean(itemsFiltered.get(position), true);
					else
						editor.putBoolean(itemsFiltered.get(position), false);
					editor.commit();
					
					notifyDataSetChanged();
					
				}
			};
			
		}
		
		public int getCount() {
			return itemsFiltered.size();
		}
		
		public Object getItem(int arg0) {
			return arg0;
		}
		
		public long getItemId(int arg0) {
			return arg0;
		}
		
		public View getView(int position, View view, ViewGroup parent) {
			
			TextView listNewEntityName;
			ImageView listNewEntityIcon;
			
			if (view == null) {
				view = getLayoutInflater().inflate(R.layout.entities_list_item_new, null);
			}
			
			listNewEntityName = (TextView) view.findViewById(R.id.listNewEntityName);
			listNewEntityIcon = (ImageView) view.findViewById(R.id.listNewEntityIcon);
			
			// Name
			listNewEntityName.setText(itemsFiltered.get(position));
			
			// Icon
			listNewEntityIcon.setTag(new Integer(position));
			
			if (watchlistSP.getBoolean(itemsFiltered.get(position), false))
				listNewEntityIcon.setImageResource(R.drawable.ok);
			else
				listNewEntityIcon.setImageResource(R.drawable.ok_bright);
			
			listNewEntityIcon.setOnClickListener(onAddClickListener);
			
			return view;
		}
		
		List<String> getFilteredResults(CharSequence constraint) {
			
			List<String> tmp = new ArrayList();
			
			for (String s : items) {
				
				if (constraint == null || s.startsWith(constraint.toString().toUpperCase())) {
					tmp.add(s);
				}
				
			}
			
			return tmp;
			
		}
		
		public Filter getFilter() {
			
			return new Filter() {
				
				protected FilterResults performFiltering(CharSequence constraint) {
					
					List<String> filteredResults = getFilteredResults(constraint);
					
					FilterResults results = new FilterResults();
					results.values = filteredResults;
					
					return results;
					
				}
				
				protected void publishResults(CharSequence constraint, FilterResults results) {
					itemsFiltered = (List<String>) results.values;
					notifyDataSetChanged();
				}
				
			};
		}
		
	}
	
	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		
		/*
		 * Log.d("stocksense", "onActivityResult " + requestCode + " " +
		 * resultCode);
		 * 
		 * if (requestCode == 64206) {
		 * 
		 * facebookHelper.saveResultToSP(data);
		 * 
		 * PendingShare pendingShare = ((StockSenseState)
		 * getApplication()).getPendingShare();
		 * 
		 * if (pendingShare != null && pendingShare.getRequestType() ==
		 * PendingShare.SiteType.FACEBOOK) {
		 * facebookHelper.shareOnFacebook(pendingShare.getImage(),
		 * pendingShare.getText()); }
		 * 
		 * }
		 */
	}
	
	private TextWatcher searchTextWatcher = new TextWatcher() {
		
		public void afterTextChanged(Editable s) {
			if (entitiesList.getAdapter() instanceof EntitiesListAdapterNew) {
				((EntitiesListAdapterNew) entitiesList.getAdapter()).getFilter().filter(s.toString());
			}
		}
		
		public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
		}
		
		public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
		}
	};
	
}
